Lesson 13

  • v1.0.0 2016.11 by David.Yi
  • v1.1 2020.5 edit by David Yi

本次内容要点

  • for break continue else:完整的 for 语句结构
  • pprint 高级打印模块使用
  • 思考一下:四则运算器

完整的 for 语句结构

  • for continue
  • for break
  • for else
  • continue 语句跳出本次循环,而 break 跳出整个循环;
  • continue 语句用来告诉 Python 跳过当前循环的剩余语句,然后继续进行下一轮循环;
  • continue 语句可以用在 while 和 for 循环中;

break 语句用来终止循环语句。

else 语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行。


In [1]:
# for continue 举例

for l in 'Python':
    if l == 'h':
        continue
    print('letter:', l)


letter: P
letter: y
letter: t
letter: o
letter: n

In [ ]:
# for continue 举例
# 去除输入的内容中的元音字母

list1 = input('Input:')

list2 = []

for s in list1:
    if s in ['a','e','i','o','u']:
        continue
    list2.append(s)

# 将列表转换为字符串
s2 = ''.join(list2)
print('Output:', s2)

In [ ]:
# for break else 举例
# 判断质数

import time

a = time.time()

for num in range(3,20):
    for i in range(2,num): 
        if num%i == 0:      
            j=num/i          
            print(num,i,'*',j)
            break            
    else:                  
        print(num, '是质数')
        
b = time.time()
print(b-a)

pprint() 介绍

pprint module提供了可以按照某个格式正确的显示 Python 已知类型数据的一种方法,这种格式很易读。


In [ ]:
import sys
print(sys.path)

In [ ]:
import sys
import pprint
pprint.pprint(sys.path)

In [ ]:
# jupyter notebook 中直接显示一些变量的结果就和采用了 pprint 的方法
 
import sys
sys.path

In [ ]:
import sys
print(type(sys.path))

思考一下

简单的四则运算器,想一下怎么实现。


In [ ]:
# 简单四则计算器代码,下面代码参考 https://www.jianshu.com/p/c22bfd91df49

def calculate():
     operation = input('''
     please type in the math operation you would like to complete:
     + for addition
     - for subtraction
     * for multiplication
     / for division
     ''')
     number_1 = float(input('Please enter the first number: '))
     number_2 = float(input('Please enter the second number: '))
     if operation == '+': 
          print('{} + {} = {} '.format(number_1, number_2,number_1 + number_2))          
                                    
     elif operation == '-':
          print('{} - {} = {} '.format(number_1,number_2,number_1 - number_2))
     elif operation == '*':                                      
          print('{} * {} = {} '.format(number_1, number_2,number_1 * number_2))
     elif operation == '/' and number_2 != 0:                                      
          print('{} / {} = {} '.format(number_1, number_2,number_1 / number_2))
     else:
          print('You have not typed a valid operator, please run the program again.')


calculate()

如果你对使用 python 来构造一种语言,比如适用一些场景的 DSL 感兴趣,如果你觉得 lex 和 yacc 这些编译原理中的概念感兴趣的话,可以参考这里:https://www.dabeaz.com/software.html

Python 下有很多优秀的包,都可以来实现语言定义和解析,但是 ply 是其中最经典的包,从2001年诞生至今,一致在维护更新,并且不断发展。

下面这个是 ply 自己带的例子,用来实现一个比较完整的计算器。因为是通过语法分析的方式实现,会比较费解,但是功能强大,并且容易扩充。


In [ ]:
# -----------------------------------------------------------------------------
# calc.py
#
# A simple calculator with variables -- all in one file.
# -----------------------------------------------------------------------------

tokens = (
    'NAME', 'NUMBER',
    'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'EQUALS',
    'LPAREN', 'RPAREN',
)

# Tokens

t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_EQUALS = r'='
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'


def t_NUMBER(t):
    r'\d+'
    try:
        t.value = int(t.value)
    except ValueError:
        print("Integer value too large %d", t.value)
        t.value = 0
    return t


# Ignored characters
t_ignore = " \t"


def t_newline(t):
    r'\n+'
    t.lexer.lineno += t.value.count("\n")


def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)


# Build the lexer
import ply.lex as lex

lexer = lex.lex()

# Parsing rules

precedence = (
    ('left', 'PLUS', 'MINUS'),
    ('left', 'TIMES', 'DIVIDE'),
    ('right', 'UMINUS'),
)

# dictionary of names
names = {}


def p_statement_assign(t):
    'statement : NAME EQUALS expression'
    names[t[1]] = t[3]


def p_statement_expr(t):
    'statement : expression'
    print(t[1])


def p_expression_binop(t):
    '''expression : expression PLUS expression
                  | expression MINUS expression
                  | expression TIMES expression
                  | expression DIVIDE expression'''
    if t[2] == '+':
        t[0] = t[1] + t[3]
    elif t[2] == '-':
        t[0] = t[1] - t[3]
    elif t[2] == '*':
        t[0] = t[1] * t[3]
    elif t[2] == '/':
        t[0] = t[1] / t[3]


def p_expression_uminus(t):
    'expression : MINUS expression %prec UMINUS'
    t[0] = -t[2]


def p_expression_group(t):
    'expression : LPAREN expression RPAREN'
    t[0] = t[2]


def p_expression_number(t):
    'expression : NUMBER'
    t[0] = t[1]


def p_expression_name(t):
    'expression : NAME'
    try:
        t[0] = names[t[1]]
    except LookupError:
        print("Undefined name '%s'" % t[1])
        t[0] = 0


def p_error(t):
    print("Syntax error at '%s'" % t.value)


import ply.yacc as yacc

parser = yacc.yacc()

while True:
    try:
        s = input('calc > ')  # Use raw_input on Python 2
    except EOFError:
        break
    parser.parse(s)

In [ ]:
# 不能直接在 notebook 中执行上面代码,%run 命令执行 python 脚本
# 执行上面的计算器代码,支持加减乘除和括号,支持变量,并且具备非常好的扩展性

%run  "calc.py"

# 1+1*2
# (1+1)*2
# (((2+3)*41)-8)+78

In [ ]: